package com.tinem.platform.module.starter.token;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.tinem.platform.module.pojo.vo.error.SystemException;
import com.tinem.platform.module.starter.sdk.MessageCode;
import com.tinem.platform.module.starter.token.config.TokenConfiguration;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author fengzhihao
 * @version v1
 * @program: platform
 * @className TokenUtil
 * @description TODO
 * @site
 * @company
 * @create 2022/1/19 12:36:31
 */
@Slf4j
public class TokenUtil {

    Map<String, TokenConfiguration.Config> config;

    public TokenUtil(List<TokenConfiguration.Config> config){
        this.config = config.stream().collect(Collectors.toMap(TokenConfiguration.Config::getClientId, Function.identity()));
    }

    public String getToken(String clientId){
        TokenConfiguration.Config config = this.config.get(clientId);
        if(config == null){
            throw new SystemException(MessageCode.ERROR_COMMONS_UNKNOWN);
        }
        // 如果token不存在，则刷新token
        if(config.getToken() == null){
            refresh(config);
        }
        // 如果token过期，则刷新token
        if(!config.getTokenExpires().after(new Date())){
            refresh(config);
        }
        return config.getToken().getString("access_token");
    }
    private void refresh(TokenConfiguration.Config config){
        config.getTokenLock().lock();
        try {
            if(config.getToken() == null){
                log.info("auth token url:{}",config.getAuthUrl());
                String res = HttpUtil.get(config.getAuthUrl());
                log.info("res:{}",res);
                config.setToken(JSON.parseObject(res));
                //获取token过期时间并提前30分钟
                config.setTokenExpires(DateUtil.offset(new Date(), DateField.SECOND,config.getToken().getInteger("expires_in")-60*30));
                log.debug("tokenExpires:{} ",DateUtil.formatDateTime(config.getTokenExpires()));
            }
        }finally {
            config.getTokenLock().unlock();
        }
    }
}
